home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Storage / Bento / MemHdr.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  9.4 KB  |  400 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        MemHdr.cpp
  3.  
  4.     Contains:    Class definition for ODMemBentoHandlers class.
  5.  
  6.     Owned by:    Vincent Lo
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <2>      5/1/96    JA        1314704: Optimize writing by leaving buffer
  13.                                     in handle past EOF. Removed unnecessary
  14.                                     MemError and Zone checking.
  15.          <6>     5/26/95    VL        1251403: Multithreading naming support.
  16.          <5>     5/16/95    EL        1249948: Implemenation truncation of memory
  17.                                     container.
  18.          <4>     12/9/94    EL        #1182308 Allows non-byte swapping
  19.                                     format/extract.
  20.          <3>    11/14/94    VL        1188257: Use Bento errors in BenotDef.h.
  21.          <2>     6/20/94    CC        ODMemoryHeap* changed to ODMemoryHeapID.
  22.          <1>     5/27/94    VL        first checked in
  23.     To Do:
  24.     
  25.     In Progress:
  26.         
  27. */
  28.  
  29. #ifndef    _ODTYPES_
  30. #include "ODTypes.h"
  31. #endif
  32.  
  33. #ifndef _MEMHDR_
  34. #include "MemHdr.h"
  35. #endif
  36.  
  37. #ifndef _BENTOHDR_
  38. #include "BentoHdr.h"
  39. #endif
  40.  
  41. #ifndef _SESSHDR_
  42. #include "SessHdr.h"
  43. #endif
  44.  
  45. #ifndef _EXCEPT_
  46. #include "Except.h"
  47. #endif
  48.  
  49. #ifndef _ODMEMORY_
  50. #include "ODMemory.h"
  51. #endif
  52.  
  53. #ifndef __CM_API__
  54. #include "CMAPI.h"
  55. #endif
  56.  
  57. #ifndef _ERRORDEF_
  58. #include "ErrorDef.xh"
  59. #endif
  60.  
  61. #ifndef _BENTODEF_
  62. #include "BentoDef.h"
  63. #endif
  64.  
  65. //==============================================================================
  66. // Constants
  67. //==============================================================================
  68.  
  69. const ODType kODBentoMemoryTypeName = "MemoryCtr";
  70.  
  71. const CMSize kExtraWriteSpace = 4*1024;        // Size of buffer to leave at end of handle
  72.  
  73. //==============================================================================
  74. // Scalar Types
  75. //==============================================================================
  76.  
  77. #if PRAGMA_ALIGN_SUPPORTED
  78. #pragma options align=mac68k
  79. #endif
  80.  
  81. struct ContainerLabelFmt {            /* Layout of a container label:            */
  82.  unsigned char  magicBytes[8];        /* 8 bytes: the magic byte identifier    */
  83.  unsigned short flags;                /* 2    the label flag                    */
  84.  unsigned short bufSize;            /* 2    TOC buffer size / 1024            */
  85.  unsigned short majorVersion;        /* 2    major format version number        */
  86.  unsigned short minorVersion;        /* 2    minor format version number        */
  87.  unsigned long    tocOffset;            /* 4    offset to start of TOC            */
  88.  unsigned long    tocSize;            /* 4    total byte size of the TOC        */
  89. };
  90. typedef struct ContainerLabelFmt ContainerLabelFmt;
  91.  
  92. #if PRAGMA_ALIGN_SUPPORTED
  93. #pragma options align=reset
  94. #endif
  95.  
  96.  
  97. #pragma segment MemHdr
  98.  
  99. //==============================================================================
  100. // ODMemBentoHandlers
  101. //==============================================================================
  102.  
  103. ODMemBentoHandlers::ODMemBentoHandlers(CMSession session, ODHandle data)
  104. {
  105.     fSession        = session;    
  106.     fData           = data;
  107.     fAllocated      = kODFalse;
  108.     fSize           = 0;
  109.     fHandleSize        = 0;
  110.     fSeekValid      = kODFalse;
  111.     fSeekPos        = 0;
  112.     fLastSeekOffset = 0;
  113.     fLastSeekMode   = 0;
  114.     fEOFReached     = kODFalse;
  115. }
  116.  
  117. ODMemBentoHandlers::~ODMemBentoHandlers()
  118. {
  119. }
  120.  
  121. void ODMemBentoHandlers::Initialize()
  122. {
  123.     CMSetMetaHandler(fSession, kODBentoMemoryTypeName, (CMMetaHandler)containerMetahandler);
  124.     
  125.     if (fData)
  126.         fSize = fHandleSize = ODGetHandleSize(fData);
  127. }
  128.  
  129. CMSession ODMemBentoHandlers::GetCMSession()
  130. {
  131.     return fSession;
  132. }
  133.  
  134. CMRefCon ODMemBentoHandlers::OpenHandler(CMOpenMode mode)
  135. {
  136. ODUnused(mode);
  137.  
  138.     if (!fData)
  139.     {
  140.         fData = ODNewHandle(0);
  141.         
  142.         fAllocated = kODTrue;
  143.         fSize = fHandleSize = 0;
  144.     }
  145.     return ((CMRefCon)this);
  146. }
  147.  
  148. void ODMemBentoHandlers::CloseHandler()
  149. {
  150.     if (fAllocated)
  151.     {
  152.         fAllocated = kODFalse;
  153.         ODDisposeHandle(fData);
  154.     }
  155. }
  156.  
  157. CMSize ODMemBentoHandlers::FlushHandler()
  158. {
  159.     if( fSize != fHandleSize ) {
  160.         ODSetHandleSize(fData,fSize);
  161.         fHandleSize = fSize;
  162.     }
  163.     return((CMSize)0);
  164. }
  165.  
  166. CMSize ODMemBentoHandlers::SeekHandler(CM_LONG posOff, CMSeekMode mode)
  167. {
  168.     int result = 0;
  169.     
  170.     /* if nothing changed since last seek there's no need for another seek    */
  171.     if ((fSeekValid) && (fLastSeekMode == mode) && (fLastSeekOffset == (long)posOff))
  172.         return (result);
  173.  
  174.     switch(mode)
  175.     {
  176.         case kCMSeekSet:
  177.             if (posOff > fSize) 
  178.             {
  179.                 fSeekPos = fSize;
  180.                 result = -1;
  181.             }
  182.             else
  183.                 fSeekPos = posOff;
  184.             break;
  185.  
  186.         case kCMSeekEnd:
  187.             if (posOff > 0) 
  188.             {
  189.                 fSeekPos = fSize;
  190.                 result = -1;
  191.             }
  192.             else
  193.             {
  194.                 fSeekPos = fSize + posOff;
  195.                 if (fSeekPos < 0)
  196.                     result = -1;
  197.             }
  198.             break;
  199.  
  200.         default:
  201.             if (fSeekPos + posOff > fSize)
  202.             {
  203.                 fSeekPos = fSize;
  204.                 result = -1;
  205.             }
  206.             else
  207.                 fSeekPos = fSeekPos + posOff;
  208.             break;
  209.     }
  210.     
  211.     fSeekValid = kODTrue;                /* indicate seek has been done            */
  212.     fLastSeekMode = mode;                /* remember the mode that we just used    */
  213.     fLastSeekOffset = (long)posOff;        /* and also the specified offset        */
  214.     
  215.     return ((CMSize)result);
  216. }
  217.  
  218. CMSize ODMemBentoHandlers::TellHandler()
  219. {    
  220.     return fSeekPos;
  221. }
  222.  
  223. CMSize ODMemBentoHandlers::ReadHandler(CMPtr buffer, CMSize elementSize, CMCount theCount)
  224. {
  225.     size_t amountRead;
  226.     
  227.     amountRead = (size_t) (elementSize * theCount);
  228.     if (fSeekPos + amountRead > fSize)
  229.     {
  230.         amountRead = (size_t) (fSize - fSeekPos);
  231.         fEOFReached = kODTrue;
  232.     }
  233.     else
  234.         fEOFReached = kODFalse;
  235.     ODBlockMove(((char *)(*((Handle) fData))) + fSeekPos, buffer, amountRead);
  236.     
  237.     fSeekPos += amountRead;
  238.     fSeekValid = 0;                    /* stream pointer has now changed    */
  239.     
  240.     return ((CMSize)amountRead);
  241. }
  242.  
  243. CMSize ODMemBentoHandlers::WriteHandler(CMPtr buffer, CMSize elementSize, CMCount theCount)
  244. {
  245.     size_t amountWritten;
  246.     OSErr  err = noErr;
  247.     
  248.     if (theCount > 0)
  249.     {
  250.         amountWritten = (size_t) (elementSize * theCount);
  251.  
  252.         if (fSeekPos + amountWritten > fHandleSize)     // Need to grow handle
  253.         {
  254.             CMSize newSize; // no ODVolatile needed
  255.             TRY{
  256.                 newSize = fSeekPos + amountWritten + kExtraWriteSpace;
  257.                 ODSetHandleSize(fData, newSize);
  258.             }CATCH_ALL{
  259.                 // Try again with no extra space at end
  260.                 newSize = fSeekPos + amountWritten;
  261.                 ODSetHandleSize(fData, newSize);
  262.             }ENDTRY
  263.             fHandleSize = newSize;
  264.         }
  265.         ODBlockMove(buffer, ((char *)(*((Handle) fData))) + fSeekPos, amountWritten);
  266.         fSeekPos += amountWritten;
  267.         fSeekValid = 0;                /* stream pointer now changed            */
  268.         
  269.         if( fSeekPos > fSize )
  270.             fSize = fSeekPos;        // Extend EOF
  271.     }
  272.     else
  273.         amountWritten = 0;
  274.         
  275.     fEOFReached = kODFalse;
  276.     
  277.     return ((CMSize)amountWritten);
  278. }
  279.  
  280. CMEofStatus ODMemBentoHandlers::EOFHandler()
  281. {
  282.     return ((CMEofStatus)fEOFReached);
  283. }
  284.  
  285. CMBoolean ODMemBentoHandlers::TruncHandler(CMSize containerSize)
  286. {
  287.     CMBoolean result = kODFalse;
  288.  
  289.     if (containerSize <= fSize) {
  290.         if (containerSize != fSize) {
  291.             ODSetHandleSize(fData, containerSize);
  292.             fSize = fHandleSize = containerSize;
  293.         }
  294.         result = kODTrue;
  295.     }
  296.     fSeekValid = 0;
  297.     return result;
  298. }
  299.  
  300. CMSize ODMemBentoHandlers::ContainerSizeHandler()
  301. {
  302.     return ((CMSize)fSize);
  303. }
  304.  
  305. void ODMemBentoHandlers::ReadLabelHandler(CMMagicBytes magicByteSequence,
  306.                                      CMContainerFlags *flags, CM_USHORT *bufSize,
  307.                                      CM_USHORT *majorVersion, CM_USHORT *minorVersion,
  308.                                      CMSize *tocOffset, CMSize *tocSize)
  309. {
  310.     unsigned long        labelSize;
  311.     ContainerLabelFmt    theLabel;
  312.  
  313.     /* Seek to the end of the label at the end of the container and read it...*/
  314.     
  315.     this->SeekHandler(-(long)sizeof(ContainerLabelFmt), kCMSeekEnd);
  316.     labelSize = (unsigned long)this->ReadHandler((CMPtr)&theLabel,
  317.                                             (CMSize)sizeof(unsigned char),
  318.                                             (CMCount)sizeof(ContainerLabelFmt));
  319.     
  320.     fSeekValid = 0;    
  321.     
  322.     if (labelSize != sizeof(ContainerLabelFmt))
  323.         THROW(kODErrBentoErr);
  324.     
  325.     /* Return all the label info... */
  326.     
  327.     ODBlockMove(theLabel.magicBytes, magicByteSequence, 8);
  328.     *flags = (CMContainerFlags)theLabel.flags;
  329.     *bufSize = (CM_USHORT)theLabel.bufSize;
  330.     *majorVersion = (CM_USHORT)theLabel.majorVersion;
  331.     *minorVersion = (CM_USHORT)theLabel.minorVersion;
  332.     *tocOffset = (CMSize)theLabel.tocOffset;
  333.     *tocSize = (CMSize)theLabel.tocSize;
  334. }
  335.  
  336. void ODMemBentoHandlers::WriteLabelHandler(CMMagicBytes magicByteSequence,
  337.                                         CMContainerFlags flags, CM_USHORT bufSize,
  338.                                         CM_USHORT majorVersion, CM_USHORT minorVersion,
  339.                                         CMSize tocOffset, CMSize tocSize)
  340. {
  341.     unsigned long        labelSize;
  342.     ContainerLabelFmt    theLabel;
  343.         
  344.     /* Fill in the label buffer with the info...                                                                                    */
  345.     
  346.     theLabel.flags        = (unsigned short)flags;
  347.     theLabel.bufSize      = (unsigned short)bufSize;
  348.     theLabel.majorVersion = (unsigned short)majorVersion; 
  349.     theLabel.minorVersion = (unsigned short)minorVersion;
  350.     theLabel.tocOffset       = (unsigned long)tocOffset;
  351.     theLabel.tocSize      = (unsigned long)tocSize;
  352.     
  353.     ODBlockMove(magicByteSequence, theLabel.magicBytes, 8);
  354.  
  355.     /* Write the label to the end of the container value... */
  356.     
  357.     this->SeekHandler(0, kCMSeekEnd);
  358.     labelSize = (unsigned long)this->WriteHandler((CMPtr)&theLabel,
  359.                                             (CMSize)sizeof(unsigned char),
  360.                                             (CMCount)sizeof(ContainerLabelFmt));
  361.     fSeekValid = kODFalse;
  362.  
  363.     if (labelSize != sizeof(ContainerLabelFmt))
  364.         THROW(kODErrBentoErr);
  365. }
  366.  
  367. CMValue ODMemBentoHandlers::ReturnParentValueHandler()
  368. {
  369.     return kODNULL;
  370. }
  371.  
  372. CM_UCHAR* ODMemBentoHandlers::ReturnContainerNameHandler()
  373. {
  374.     return kODNULL;
  375. }
  376.  
  377. CMType ODMemBentoHandlers::ReturnTargetTypeHandler(CMContainer container)
  378. {
  379. ODUnused(container);
  380.  
  381.     return kODNULL;
  382. }
  383.  
  384. void ODMemBentoHandlers::ExtractDataHandler(CMDataBuffer buffer,
  385.                                                  CMSize size, CMPrivateData data)
  386. {
  387.     if ((ODSLong)size < 0)            /* this means it is endian-ness netural    */
  388.         size = -(ODSLong)size;
  389.     ODBlockMove(buffer, data, (size_t)size);
  390. }
  391.  
  392. void ODMemBentoHandlers::FormatDataHandler(CMDataBuffer buffer,
  393.                                      CMSize size, CMPrivateData data)
  394. {
  395.     if ((ODSLong)size < 0)            /* this means it is endian-ness netural    */
  396.         size = -(ODSLong)size;
  397.  
  398.     ODBlockMove(data, buffer, (size_t)size);
  399. }
  400.